www.gusucode.com > VC++使用XOR 256算法对文件进行加密解密-源码程序 > VC++使用XOR 256算法对文件进行加密解密-源码程序/code/HexEnc_src/HexEncDoc.cpp

    //Download by http://www.NewXing.com
// HexEncDoc.cpp : implementation of the CHexDoc class
//

#include "stdafx.h"
#include <math.h>
#include "HexEnc.h"

#include "HexEncDoc.h"
#include "InputDialog.h"
#include "WaitingDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CHexDoc

IMPLEMENT_DYNCREATE(CHexDoc, CDocument)

BEGIN_MESSAGE_MAP(CHexDoc, CDocument)
	//{{AFX_MSG_MAP(CHexDoc)
	ON_COMMAND(ID_ACTION_ENCODE, OnActionEncode)
	ON_COMMAND(ID_ACTION_DECODE, OnActionDecode)
	ON_UPDATE_COMMAND_UI(ID_ACTION_DECODE, OnUpdateAction)
	ON_UPDATE_COMMAND_UI(ID_ACTION_ENCODE, OnUpdateAction)
	ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateAction)
	ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS, OnUpdateAction)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CHexDoc construction/destruction

CHexDoc::CHexDoc()
{
	// TODO: add one-time construction code here
	m_nDocLength = 0;
	m_pFileData = NULL;
	m_nKey = 1;

}

CHexDoc::~CHexDoc()
{
}

/////////////////////////////////////////////////////////////////////////////
// CHexDoc serialization

void CHexDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
		if(m_pFileData != NULL)
		{
			CFile* pFile = ar.GetFile();
			try {
				pFile->Write(m_pFileData, m_nDocLength);
			}
			catch(CFileException* e) {
				::MessageBox(NULL, _T("File save failed!"), 
						   _T("Warning!"), MB_ICONSTOP | MB_OK);
				throw e;
			}
		}
	}
	else
	{
		// TODO: add loading code here
		CFile* pFile = ar.GetFile();
		m_nDocLength = pFile->GetLength();

		try {
			m_pFileData = new BYTE[m_nDocLength];
		}
		catch(CMemoryException* e) {
			m_nDocLength = 0;
			throw e;
		}

		try {
			pFile->Read(m_pFileData, m_nDocLength);
		}
		catch(CFileException* e) {
			delete[] m_pFileData;
			m_pFileData = NULL;
			m_nDocLength = 0;
			throw e;
		}	
	}
}

/////////////////////////////////////////////////////////////////////////////
// CHexDoc diagnostics

#ifdef _DEBUG
void CHexDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CHexDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CHexDoc commands

void CHexDoc::DeleteContents() 
{	
	CDocument::DeleteContents();

	if(m_pFileData != NULL)
	{
		delete[] m_pFileData;
		m_pFileData = NULL;
		m_nDocLength = 0;
	}
}

UINT CHexDoc::GetBytes(UINT nIndex, UINT nCount, PVOID pBuffer)
{
	if (nIndex >= m_nDocLength)
        return 0;

    UINT nLength = nCount;
    if ((nIndex + nCount) > m_nDocLength)
        nLength = m_nDocLength - nIndex;

    ::CopyMemory (pBuffer, m_pFileData + nIndex, nLength);
    return nLength;
}

UINT CHexDoc::GetDocumentLength()
{
	return m_nDocLength;
}

void CHexDoc::OnActionEncode() 
{
	CInputDialog dlg;
	
	if(dlg.DoModal() == IDOK)
	{
		m_nKey = dlg.m_nKey;

		CWaitingDialog waitingDlg;
		waitingDlg.Create(IDD_WAITING);
		waitingDlg.ShowWindow(SW_SHOW);
		waitingDlg.CenterWindow();
		waitingDlg.UpdateWindow();
		waitingDlg.SetActiveWindow();

		KeyGen((DWORD)m_nKey);
		EncodeFile();

		waitingDlg.SendMessage(WM_CLOSE);
		AfxMessageBox(_T("Encryption finished!"));
	}
}

void CHexDoc::OnActionDecode() 
{
	CInputDialog dlg;
	
	if(dlg.DoModal() == IDOK)
	{
		m_nKey = dlg.m_nKey;

		CWaitingDialog waitingDlg;
		waitingDlg.Create(IDD_WAITING);
		waitingDlg.ShowWindow(SW_SHOW);
		waitingDlg.CenterWindow();
		waitingDlg.UpdateWindow();
		waitingDlg.SetActiveWindow();

		KeyGen((DWORD)m_nKey);
		DecodeFile();
		
		waitingDlg.SendMessage(WM_CLOSE);
		AfxMessageBox(_T("Decryption finished!"));
	}
}

// encrypt the file
void CHexDoc::EncodeFile()
{
	DWORD* pdwTemp;

	for(UINT i = 0; i < m_nDocLength; i += 16)
	{
		pdwTemp = (DWORD*)&m_pFileData[i];

		pdwTemp[0] = (pdwTemp[0] - m_dwS[2 * R + 2]);
		pdwTemp[2] = (pdwTemp[2] - m_dwS[2 * R + 3]);

		for(int j = R; j >= 1; j--)
		{
			DWORD temp = pdwTemp[3];
			pdwTemp[3] = pdwTemp[2];
			pdwTemp[2] = pdwTemp[1];
			pdwTemp[1] = pdwTemp[0];
			pdwTemp[0] = temp;

			DWORD t = LeftRotate((pdwTemp[1] * (2 * pdwTemp[1] + 1)),
								OffsetAmount((DWORD)(log((double)W)/log(2.0))));
			DWORD u = LeftRotate((pdwTemp[3] * (2 * pdwTemp[3] + 1)),
								OffsetAmount((DWORD)(log((double)W)/log(2.0))));
			pdwTemp[0] = (RightRotate((pdwTemp[0] - m_dwS[2 * j]), OffsetAmount(u))) ^ t;
			pdwTemp[2] = (RightRotate((pdwTemp[2] - m_dwS[2 * j + 1]), OffsetAmount(t))) ^ u;
		}

		pdwTemp[1] = (pdwTemp[1] - m_dwS[0]);
		pdwTemp[3] = (pdwTemp[3] - m_dwS[1]);
	}
	pdwTemp = NULL;
	SetModifiedFlag(TRUE);

	POSITION pos = GetFirstViewPosition();
	while(pos != NULL)
	{
		CView* pView = GetNextView(pos);
		pView->RedrawWindow();
	}
}

// decrypt the file
void CHexDoc::DecodeFile()
{
	DWORD* pdwTemp;

	for(UINT i = 0; i < m_nDocLength; i += 16)
	{
		pdwTemp = (DWORD*)&m_pFileData[i];

		pdwTemp[1] = (pdwTemp[1] + m_dwS[0]);
		pdwTemp[3] = (pdwTemp[3] + m_dwS[1]);

		for(int j = 1; j <= R; j++)
		{
			DWORD t = LeftRotate((pdwTemp[1] * (2 * pdwTemp[1] + 1)),
								OffsetAmount((DWORD)(log((double)W)/log(2.0))));
			DWORD u = LeftRotate((pdwTemp[3] * (2 * pdwTemp[3] + 1)),
								OffsetAmount((DWORD)(log((double)W)/log(2.0))));
			pdwTemp[0] = (LeftRotate(pdwTemp[0] ^ t, OffsetAmount(u)) + m_dwS[2 * j]);
			pdwTemp[2] = (LeftRotate(pdwTemp[2] ^ u, OffsetAmount(t)) + m_dwS[2 * j + 1]);

			DWORD temp = pdwTemp[0];
			pdwTemp[0] = pdwTemp[1];
			pdwTemp[1] = pdwTemp[2];
			pdwTemp[2] = pdwTemp[3];
			pdwTemp[3] = temp;
		}

		pdwTemp[0] = (pdwTemp[0] + m_dwS[2 * R + 2]);
		pdwTemp[2] = (pdwTemp[2] + m_dwS[2 * R + 3]);
	}
	pdwTemp = NULL;
	SetModifiedFlag(TRUE);

	POSITION pos = GetFirstViewPosition();
	while(pos != NULL)
	{
		CView* pView = GetNextView(pos);
		pView->RedrawWindow();
	}
}

void CHexDoc::KeyGen(DWORD dwKey)
{
	DWORD P32 = 0xB7E15163;
	DWORD Q32 = 0x9E3779B9;
	DWORD i, A, B;
	DWORD dwByteOne, dwByteTwo, dwByteThree, dwByteFour;

	dwByteOne = dwKey >> 24;
	dwByteTwo = dwKey >> 8;
	dwByteTwo = dwByteTwo & 0x0010;
	dwByteThree = dwKey << 8;
	dwByteThree = dwByteThree & 0x0100;
	dwByteFour = dwKey << 24;

	dwKey = dwByteOne | dwByteTwo | dwByteThree | dwByteFour;

	m_dwS[0] = P32;

	for(i = 1; i < 2 * R + 4; i++)
		m_dwS[i] = m_dwS[i - 1] + Q32;

	i = A = B = 0;

	int v = 3 * max(1, 2 * R + 4);

	for(int s = 1; s <= v; s++)
	{
		A = m_dwS[i] = LeftRotate(m_dwS[i] + A + B, OffsetAmount(3));
		B = dwKey = LeftRotate(dwKey + A + B, OffsetAmount(A + B));

		i = (i + 1) % (2 * R + 4);
	}
}

DWORD CHexDoc::OffsetAmount(DWORD dwVar)
{
	int nLgw = (int)(log((double)W)/log(2.0));

	dwVar = dwVar << (W - nLgw);
	dwVar = dwVar >> (W - nLgw);
	return dwVar;
}

DWORD CHexDoc::LeftRotate(DWORD dwVar, DWORD dwOffset)
{
	DWORD temp1, temp2;

	temp1 = dwVar >> (W - dwOffset);
	temp2 = dwVar << dwOffset;
	temp2 = temp2 | temp1;

	return temp2;
}

DWORD CHexDoc::RightRotate(DWORD dwVar, DWORD dwOffset)
{
	DWORD temp1, temp2;

	temp1 = dwVar << (W - dwOffset);
	temp2 = dwVar >> dwOffset;
	temp2 = temp2 | temp1;

	return temp2;
}

void CHexDoc::OnUpdateAction(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(m_nDocLength != 0);
	
}